package cn.johnyu.filter;

import cn.johnyu.domain.Account;
import cn.johnyu.service.AuthenPersistenceService;
import cn.johnyu.util.GsonUtil;
import cn.johnyu.util.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.ReactiveSecurityContextHolder;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebFilter;
import org.springframework.web.server.WebFilterChain;
import reactor.core.publisher.Mono;
import reactor.util.context.Context;

import java.util.List;
@Slf4j
public class CheckTokenFilter implements WebFilter {
    private  AuthenPersistenceService authenPersistenceService;
    public CheckTokenFilter(AuthenPersistenceService authenPersistenceService) {
        this.authenPersistenceService = authenPersistenceService;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        String path = exchange.getRequest().getPath().value();
        String method = exchange.getRequest().getMethod().toString();
        log.info("method:{},path:{}",method,path);
        String jwtToken = exchange.getRequest().getHeaders().getFirst("Token");
        if(jwtToken==null){
            log.info("请求中没有Token,直接放行给授权处理器");
            return chain.filter(exchange);
        }
        log.info("获取到jwtToken，解析中...   ");

      return   authenPersistenceService.check(jwtToken)
                .flatMap(rs->{
                    if(rs){
                        Account account = GsonUtil.jsonToAccount(JwtUtil.fromToken(jwtToken));
                        log.info("account:{}",account);
//                        List<SimpleGrantedAuthority> authorities = account.getAuthorities().stream().map(auth -> new SimpleGrantedAuthority(auth)).toList();
                        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(account.getUsername(), null,account.getAuthorities());

                        Context context = ReactiveSecurityContextHolder.withAuthentication(authenticationToken);
                        return chain.filter(exchange).contextWrite(context);
                    }
                    else{
                        log.info("token无效，直接放行给授权处理器");
                        return chain.filter(exchange);
                    }
                });
    }
}
